package com.gbase8c.dmt.model.migration.dto;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.gbase8c.dmt.common.util.JsonMapper;
import com.gbase8c.dmt.model.enums.DbType;
import lombok.*;
import org.beetl.core.BeetlKit;

import java.io.Serializable;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
// 数据源dto
public class DataSourceDto implements Serializable {
    private static final long serialVersionUID = -8352412494140222602L;

    private String id;
    private String name;
    private PropertyType propertyType;
    private DbType dbType;
    private DbType.DbVersion dbVersion;
    private String username;
    private String password;
    private String gbase8cDbType;

    private Map<String, Object> properties;
    private String propertiesJson;
    private String lastRecv;

    private ServiceStatus serviceStatus;

    private String connInfo;

    private boolean canTurn = false;

    private String groupName;
    private boolean clusterMaster = false;

    public Map<String, Object> getProperties(){
        if (properties != null) {
            return properties;
        }else if( propertiesJson != null) {
            Map map = new JsonMapper().fromJson(propertiesJson,Map.class);
            return  map;
        }else{
            return null;
        }
    }

    public Object get(String key) {
        if (properties != null) {
            return properties.get(key);
        }else if( propertiesJson != null) {
            Map map = new JsonMapper().fromJson(propertiesJson,Map.class);
            return  map.get(key);
        }else{
            return null;
        }
    }

    @JsonIgnore
    public String getNameWithSwitchOff(){
        String str = this.name;
        if(str.endsWith(".switchoff")){
            str = str.substring(0,str.length()-10);
        }else{

        }
        return str;
    }

    public boolean isSameConnection(DataSourceDto one){
        boolean dbt = this.getDbType().equals(one.getDbType());
        boolean dbv = this.getDbVersion().equals(one.getDbVersion());
        boolean dbn = this.getName().equals(one.getName());
        boolean dbp = this.getPassword().equals(one.getPassword());

        boolean dbna = this.getProperties().get("dbName").equals(one.getProperties().get("dbName"));
        boolean dbh = this.getProperties().get("host").equals(one.getProperties().get("host"));
        boolean dbpp = this.getProperties().get("port").equals(one.getProperties().get("port"));


        return dbt &&
                dbv &&
                dbn &&
                dbp &&
                dbna &&
                dbh &&
                dbpp
                ;




    }

    public enum PropertyType {
        Detail, JdbcUrl
    }

    public enum ServiceStatus {
        Online, Offline, SwitchOff, SwitchOn;
    }


    @JsonIgnore
    public String getDriverClass() {
        DbType.DbVersion dbVersion = getDbVersion();
        String driverClass = dbVersion.getDriverClass();
        if (driverClass == null) {
            DbType dbType = getDbType();
            driverClass = dbType.getDriverClass();
        }
        return driverClass;
    }

    @JsonIgnore
    public String getJdbcUrl() {
        String jdbcUrl = null;
        PropertyType propertyType = getPropertyType();

        //如果指定了PropertyType为JdbcUrl则直接从properties属性中获取
        if (propertyType.equals(PropertyType.JdbcUrl)) {
            jdbcUrl = get("jdbcUrl").toString();
        } else {

            //否则的话根据properties去拼接一个jdbcUrl
            DbType.DbVersion dbVersion = getDbVersion();
            String urlTemplate = dbVersion.getJdbcUrl();
            if (urlTemplate == null) {
                DbType dbType = getDbType();
                urlTemplate = dbType.getJdbcUrl();
            }
            // change by +7 for yzf
            Map<String, Object> prop = null;
            if(getProperties() == null){
                prop = new JsonMapper().fromJson(propertiesJson,Map.class);
            }else{
                prop = getProperties();
            }
//            Map<String,Object> map =  JSONObject.parse(propertiesJson);
//            jdbcUrl = jdbcUrl(urlTemplate, getProperties());
            jdbcUrl = jdbcUrl(urlTemplate, prop);
            // change by +7 for yzf end ;
        }
        return jdbcUrl;
    }

    private String jdbcUrl(String urlTemplate, Map<String, Object> properties) {
        return BeetlKit.render(urlTemplate, properties);
    }

    public String dbName(){
        String dbName = "";
        PropertyType propertyType = getPropertyType();
        if (propertyType.equals(PropertyType.JdbcUrl)) {
            dbName = dbName(this.get("jdbcUrl").toString());
        } else {
            switch (this.dbType){
                case Oracle:
                    dbName = this.getProperties().get("connectValue").toString();
                    break;
                default:
                    dbName = this.getProperties().get("dbName").toString();
            }

        }

        return dbName;
    }


    private static String dbName(String jdbcUrl){
        String pc = "jdbc:(?<db>\\w+):.*((//)|@)(?<host>.+):(?<port>\\d+)(/|(;DatanaseName=)|:)(?<dbName>\\w+)\\??.*";
        Pattern p = Pattern.compile(pc);
        Matcher m = p.matcher(jdbcUrl);
        String res = null;
        if(m.find()){
            res = m.group("dbName");
        }
        return res;
    }
}
